home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 104_01 / c2.c < prev    next >
Text File  |  1980-01-01  |  13KB  |  511 lines

  1.  
  2.  
  3. #ifndef TRUE    /* see if need include file */
  4. #include <c.def>
  5. #endif
  6.  
  7. /*                    */
  8. /*    Get required array size        */
  9. /*                    */
  10. /* invoked when declared variable is follwed by "[" */
  11. /*      this routine makes subscript the absolute */
  12. /*      size of the array. */
  13. needsub()
  14. {
  15.     int num[1];
  16.     if (match("]")) return 0;    /* null size */
  17.     if (number(num)==0) {        /* go after a number */
  18.         error("must be constant");     /* it isn't */
  19.         while(ch() != ',' && ch() != ';' && ch()) gch();
  20.         return 1; 
  21.         }
  22.     if (num[0]<0) {
  23.         error("negative size illegal");
  24.         num[0]=(-num[0]);
  25.         }
  26.     needbrack("]");        /* force single dimension */
  27.     return num[0];        /* and return size */
  28.     }
  29. /*                */
  30. /*      Begin a function    */
  31. /*                */
  32. /* Called from "parse" this routine tries to make a function */
  33. /*      out of what follows.    */
  34. newfunc()
  35. {
  36.     char n[namesize],*ptr;
  37.     if (symname(n) == 0) {
  38.         error("illegal function or declaration");
  39.         kill();
  40.         return;
  41.         }
  42.     if (!match("(")) {
  43.         error("illegal function or declaration");
  44.         kill();
  45.         return;
  46.         }
  47.     if(ptr=findglb(n)) {      /* already in symbol table ? */
  48.         if (ptr[ident] != function) multidef(n);
  49.             /* already variable by that name */
  50.         else if(ptr[offset] == function) multidef(n);
  51.             /* already function by that name */
  52.         else {
  53.             ptr[offset]=function;
  54.             csect(n);
  55.             }
  56.             /* otherwise we have what was earlier*/
  57.             /*  assumed to be a function */
  58.         }
  59.     /* if not in table, define as a function now */
  60.     else {
  61.         /* fill in gobal symbol table */
  62.         if (glbptr>=endglb) 
  63.             error("gobal symbol table overflow");
  64.         else {
  65.             ptr=glbptr;
  66.             glbptr+=symsiz;
  67.             strcpy(ptr+name,n);
  68.             ptr[ident]=function;
  69.         ]=cint;
  70.             ptr[offset]=function;
  71.             ptr[offset1]=
  72.             ptr[indcnt]=
  73.             ptr[storage]=0;
  74.             }
  75.         csect(n);
  76.         }
  77.  
  78.     argstk=0;           /* init arg count */
  79.     while(match(")") == 0) {    /* then count args */
  80.         /* any legal name bumps arg count */
  81.         if (symname(n)) argstk=argstk+2;
  82.         else{
  83.             error("illegal argument name");
  84.             junk();
  85.             }
  86.         blanks();
  87.         /* if not closing paren, should be a comma */
  88.         if( streq(line+lptr,")") == 0) {
  89.             if(match(",")==0)
  90.             error("expected comma");
  91.             }
  92.         if(endst())break;
  93.         }
  94.     locptr=startloc;    /* "clear" local symbol table*/
  95.     sp=0;           /* preset stack ptr */
  96.     while(argstk) {
  97.         /* now let user declare what types of things */
  98.         /*      those arguments were */
  99.         if (amatch("char",4)) {
  100.             getarg(cchar);
  101.             ns();
  102.             }
  103.         else if (amatch("int",3)) {
  104.             getarg(cint);
  105.             ns();
  106.             }
  107.         else {
  108.             error("wrong number args");
  109.             break;
  110.             }
  111.         }
  112.     if(statement()!=streturn)  {
  113.             /* do a statement, but if */
  114.             /* it's a return, skip */
  115.             /* cleaning up the stack */
  116.         modstk(0);
  117.         ret();
  118.         }
  119.     sp=0;
  120.     locptr=startloc;
  121.     dumplits();
  122.     litlab=getlabel();
  123.     }
  124. /*                      */
  125. /*      Declare argument types      */
  126. /*                      */
  127. /* called from "newfunc" this routine adds a entry in the */
  128. /*      local symbol table for each named argument */
  129. getarg(t)           /* t = cchar or cint */
  130. int t;
  131. {
  132.     char n[namesize],c;int j,count;
  133.     while(1) {
  134.         count=0;
  135.         if (argstk == 0) return;   /* no more args */
  136.         if (match("*")) {
  137.             j=pointer;
  138.             ++count;
  139.             while(ch()=='*') {
  140.                 ++count;
  141.                 gch();
  142.                 }
  143.             }
  144.         else j=variable;
  145.         if (symname(n) == 0) illname();
  146.         if (findloc(n)) multidef(n);
  147.         data_parse(n,t,stkarg,j,count);
  148.         if(endst())return;
  149.         if(match(",")==0)error("expected comma");
  150.         }
  151.     }
  152. /*                      */
  153. /*      Statement parser        */
  154. /*                      */
  155. /* called whenever syntax requires      */
  156. /*      a statement.             */
  157. /*  this routine performs that statement */
  158. /*  and returns a number telling which one */
  159. statement()
  160.  {      if (!ch() && eof) return;
  161.     else if(amatch("char",4)) {
  162.         declloc(cchar);
  163.         ns();
  164.         }
  165.     else if(amatch("int",3)) {
  166.         declloc(cint);
  167.         ns();
  168.         }
  169.     else if(match("{")) compound();
  170.     else if(amatch("if",2)) {
  171.         doif();
  172.         lastst=stif;
  173.         }
  174.     else if(amatch("while",5)) {
  175.         dowhile();
  176.         lastst=stwhile;    
  177.         }
  178.     else if (amatch("for",3)) {
  179.         dofor();
  180.         lastst=stfor;
  181.         }
  182.     else if (amatch("switch",6)) {
  183.         doswitch();
  184.         lastst=stswitch;
  185.         }
  186.     else if(amatch("return",6)) {
  187.         doreturn();
  188.         ns();
  189.         lastst=streturn;
  190.         }
  191.     else if(amatch("break",5)) {
  192.         dobreak();
  193.         ns();
  194.         lastst=stbreak;
  195.         }
  196.     else if(amatch("continue",8)) {
  197.         docont();
  198.         ns();
  199.         lastst=stcont;
  200.         }
  201.     else if(match(";"));
  202.     else if(match("#asm")) {
  203.         doasm();
  204.         ns();
  205.         lastst=stasm;
  206.         }
  207.     /* if nothing else, assume it's an expression */
  208.     else {
  209.         expression();
  210.         ns();
  211.         lastst=stexp;
  212.         }
  213.     return lastst;
  214.     }
  215. /*                      */
  216. /*      Semicolon enforcer          */
  217. /*                      */
  218. /* called whenever syntax requires a semicolon */
  219. ns()    {if(match(";")==0)error("missing semicolon");}
  220. /*                    */
  221. /*    need semicolon            */
  222. /*    written    by Mike    Bernson    1/81    */
  223. /*                    */
  224. needsem()
  225. {
  226.     if (match(";"))    return FALSE;
  227.     error("Missing semicolon");
  228.     junk();
  229.     return TRUE;
  230.     }
  231. /*                    */
  232. /*    need opening parn        */
  233. /*    written    by Mike    Bernson    1/81    */
  234. needoparn()
  235. {
  236.     if (match("("))    return FALSE;
  237.     error("Missing left parnthis");
  238.     junk();
  239.     return TRUE;
  240.     }
  241. /*                    */
  242. /*    need closing parn        */
  243. /*    written    by Mike    Bernson    1/81    */
  244. needcparn()
  245. {
  246.     if (match(")"))    return FALSE;
  247.     error("Missing right parnthis");
  248.     junk();
  249.     return TRUE;
  250.     }
  251. /*                    */
  252. /*    need opening brace        */
  253. /*    written    by Mike    Bernson    1/81    */
  254. needobrace()
  255. {
  256.     if (match("{"))    return FALSE;
  257.     error("Missing left brace");
  258.     junk();
  259.     return TRUE;
  260.     }
  261. /*                    */
  262. /*    need closing brace        */
  263. /*    written    by Mike    Bernson    1/81    */
  264. needcbrace()
  265. {
  266.     if (match("}"))    return FALSE;
  267.     error("Missing right brace");
  268.     junk();
  269.     return TRUE;
  270.     }
  271. /*                      */
  272. /*      Compound statement          */
  273. /*                      */
  274. /* allow any number of statements to fall between "{}" */
  275. compound()
  276.     {
  277.     ++ncmp;     /* new level open */
  278.     while(match("}")==0)
  279.         if(eof) return;
  280.         else statement();
  281.     --ncmp;     /* close current level */
  282.     }
  283. /*                      */
  284. /*          "if" statement      */
  285. /*                      */
  286. doif()
  287.     {
  288.     int flev,fsp,flab1,flab2;
  289.     flev=locptr;    /* record current local level */
  290.     fsp=sp;     /* record current stk ptr */
  291.     flab1= getlabel(); /* get label for false branch */
  292.     test(flab1);    /*get expression, and branch false */
  293.     statement();    /* if true, do a statement */
  294.     sp=modstk(fsp); /* then clean up the stack */
  295.     locptr=flev;    /* and deallocate any locals */
  296.     if (amatch("else",4)==0)    /* if...else ? */
  297.         /* simple "if"...print false label */
  298.         {sprintlabel(flab1);
  299.         return; /* and exit */
  300.         }
  301.     /* an "if...else" statement. */
  302.     jump(flab2=getlabel()); /* jump around the false code */
  303.     sprintlabel(flab1);    /* print true label */
  304.     statement();        /* and do else clause */
  305.     sp=modstk(fsp);        /* then clean up stack ptr */
  306.     locptr=flev;        /* dellocate locals */
  307.     sprintlabel(flab2);    /* print true label */
  308.     }
  309. /*                      */
  310. /*      "while" statement           */
  311. /*                      */
  312. dowhile()
  313.     {
  314.     int que[wqsiz];                /* allocate local queue */
  315.  
  316.     que[wqsym]=locptr;          /* record local level */
  317.     que[wqsp]=sp;               /* and stk ptr */
  318.     que[wqloop]=            /* and looping label */
  319.     que[wqend]=getlabel();        /* continue label */
  320.     que[wqlab]=getlabel();        /* and exit label */
  321.     addwhile(que);            /* add to looping stack    */
  322.     sprintlabel(que[wqloop]);    /* loop label */
  323.     test(que[wqlab]);        /* see if true */
  324.     statement();            /* if so, do a statement */
  325.     jump(que[wqloop]);        /* loop    to label */
  326.     sprintlabel(que[wqlab]);    /* exit label */
  327.     locptr=que[wqsym];        /* deallocate locals */
  328.     sp=modstk(que[wqsp]);        /* clean up stk    ptr */
  329.     delwhile();            /* delete queue    entry */
  330.     }
  331. /*                    */
  332. /*    "Switch" statement        */
  333. /*                    */
  334. /*    written by Mike Bernson 1/81    */
  335. /*                    */
  336. doswitch()
  337. {
  338.     int value[SWITCH_MAX];  /* value for case statemant */
  339.     int label[SWITCH_MAX];  /* value for each label */
  340.     int count,tenp;     /* number of switches */
  341.     int end_label;      /* label for default */
  342.     int label_switch;    /* used for switch label */
  343.     int temp,val[2];
  344.     int que[wqsiz];        /* local que area */
  345.     count=0;        /* number of case statements */
  346.     que[wqsym]=locptr;    /* local vable poin